/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
//
//
*/

#ifndef __UMC_AVS_ENC_COMPRESSOR_H
#define __UMC_AVS_ENC_COMPRESSOR_H

#include "umc_base_codec.h"
#include "umc_avs_enc.h"
#include "umc_avs_dec_decompressor.h"
#include "umc_me.h"

namespace UMC
{

#define m_encCtx m_decCtx
#define SetEncodingContext SetDecodingContext
#define GetEncodingContext GetDecodingContext
#define PrepareEncoding PrepareDecoding
#define AdvanceEncoding AdvanceDecoding
#define FinalizeEncoding FinalizeDecoding

class AVSCompressor : public AVSDecompressor
{
public:
    // Default constructor
    AVSCompressor(void);
    // Destructor
    virtual
    ~AVSCompressor(void);

    //
    // Initialization functions
    //
    // Copy avs encoder params
    void CopyEncoderParams(BaseCodecParams* pCodecParams);

    // Set reconstructing parameters
    inline
    void SetDisassemblingContext(AVS_DISASSEMBLING_CONTEXT &disCtx);
    // Get reconstructing parameters
    inline
    AVS_DISASSEMBLING_CONTEXT & GetDisassemblingContext(void);

    //
    // Combined functions to compress
    //
    void CompressIMacroBlocksRow(void);
    void CompressPMacroBlocksRow(void);
    void CompressBMacroBlocksRow(void);

protected:

    // pointer on the copy of encoder's params
    const AVSVideoEncoderParams* m_pAVSCompressorParams;

    // Prepare disassembling variables
    void PrepareDisassembling(void);

    // Update disassembling variables
    void AdvanceDisassembling(void);

    // Finalize disassembling stuff, set specials flags
    void FinalizeDisassembling(void);

    // encode slice header into bitstream
    void CompressSliceHeader(void);

    void EncodeIMacroBlock(void);
    void EncodePMacroBlock(void);
    void EncodeBMacroBlock(void);

    void EncodePMacroBlockType(void);
    void EncodeSkipPMacroBlock(void);
    void EncodeSkipBMacroBlock(void);

    Ipp32u GetSizeIMacroBlock(void);
    Ipp32u GetSizePMacroBlock(void);
    Ipp32u GetSizeBMacroBlock(void);

    void DisassembleIMacroBlock(void);
    void DisassemblePMacroBlock(void);
    void DisassembleBMacroBlock(void);

    void FillUpMeMbStatIMacroBlock(void);
    void FillUpMeMbStatPMacroBlock(void);
    void FillUpMeMbStatBMacroBlock(void);

    // Encode intra prediction mode
    void EncodeIntraPredModeISlice(AVS_MB_INFO *pLeft, AVS_MB_INFO *pTop, Ipp32s iBlockNum);
    Ipp32u GetSizeIntraPredModeISlice(AVS_MB_INFO *pLeft, AVS_MB_INFO *pTop, Ipp32s iBlockNum);

    // For P frames
    void GetRefIndiciesPSlice(void);
    void GetDiffMotionVectorsPSlice(void);

    // For B frames
    void GetRefIndiciesBSlice(void);
    void GetDiffMotionVectorsBSlice(void);
    void GetDiffMotionVectorsBSlice16x16(void);
    void GetDiffMotionVectorsBSlice16x8(void);
    void GetDiffMotionVectorsBSlice8x16(void);
    void GetDiffMotionVectorsBSlice8x8(void);

    // overloaded functions in AVSCompressor for MC
    void CompensateMotionLumaPMacroBlock(Ipp8u *pDst, Ipp32s dstStep);
    void CompensateMotionLumaBMacroBlock(Ipp8u *pDst, Ipp32s dstStep);
    void CompensateMotionChromaPMacroBlock(Ipp8u *pDstU, Ipp8u *pDstV, Ipp32s dstStep);
    void CompensateMotionChromaBMacroBlock(Ipp8u *pDstU, Ipp8u *pDstV, Ipp32s dstStep);
    void CompensateMotionLumaBiDir(Ipp32s blockNum);
    void CompensateMotionChromaBiDir(Ipp32s blockNum);

    // for debug only!!! Reconstruction in the encoder the same as in decoder!
    //void ReconstructPMacroBlock(void);
    //void ReconstructBMacroBlock(void);

    AVS_DISASSEMBLING_CONTEXT m_disCtx;                         // (AVS_DISASSEMBLING_CONTEXT) disassembling context

    Ipp32u m_extraBitSize;                                      // (Ipp32u) extra available bits
    Ipp32u m_maxMbBitSize;                                      // (Ipp32u) maximum bits per macroblock

};

inline
void AVSCompressor::SetDisassemblingContext(AVS_DISASSEMBLING_CONTEXT &disCtx)
{
    m_disCtx = disCtx;

} // void AVSCompressor::SetDisassemblingContext(AVS_DISASSEMBLING_CONTEXT &disCtx)

inline
AVS_DISASSEMBLING_CONTEXT & AVSCompressor::GetDisassemblingContext(void)
{
    return m_disCtx;

} // AVS_DISASSEMBLING_CONTEXT & AVSCompressor::GetDisassemblingContext(void)

} // namespace UMC

#endif // __UMC_AVS_ENC_COMPRESSOR_H
